﻿using System;
using System.Collections.Generic;
using System.Linq;
using Loki.Resources;
using Loki.Utils;

namespace Loki.Engine
{
    /// <summary>
    /// Service container base class.
    /// </summary>
    public class ServiceModel : LokiObject, IDisposable
    {
        #region Service registering

        private Dictionary<Guid, IService> _Services = new Dictionary<Guid, IService>();

        public void RegisterService<TServiceInterface>(TServiceInterface P_Service) where TServiceInterface : IService
        {
            Log.InfoFormat(LogStrings.ServiceModel_RegisterService, P_Service.Name, P_Service.ID, typeof(TServiceInterface).Name);
            _Services[P_Service.ID] = P_Service;
        }

        public TServiceInterface GetService<TServiceInterface>() where TServiceInterface : IService
        {
            return (TServiceInterface)_Services.Values.FirstOrDefault(x => x is TServiceInterface);
        }

        #endregion Service registering

        #region Disposable

        /// <summary>
        /// Releases all resources used by an instance of the <see cref="ServiceModel" /> class.
        /// </summary>
        /// <remarks>
        /// This method calls the virtual <see cref="Dispose(bool)" /> method, passing in
        /// <strong>true</strong>, and then suppresses finalization of the instance.
        /// </remarks>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~ServiceModel()
        {
            Dispose(false);
        }

        /// <summary>
        /// Releases the unmanaged resources used by an instance of the <see cref="ServiceModel" />
        /// class and optionally releases the managed resources.
        /// </summary>
        /// <param name="P_Disposing"><strong>True</strong> to release both managed and unmanaged
        /// resources; <strong>false</strong> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool P_Disposing)
        {
            if (P_Disposing)
            {
                foreach (var L_Service in _Services.Values.OfType<IDisposable>())
                {
                    L_Service.Dispose();
                }
            }
        }

        #endregion Disposable
    }
}